package io.litchi.auth.application.service;

import io.jsonwebtoken.Claims;
import io.litchi.auth.Infrastructure.common.result.login.RefreshTokenResult;
import io.litchi.auth.Infrastructure.config.AuthConfig;
import io.litchi.auth.Infrastructure.exception.type.RefreshTokenExpiredException;
import io.litchi.common.result.Result;
import io.litchi.starter.jjwt.JwtManager;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;

import java.util.Objects;

/**
 * description: 处理无需认证接口
 *
 * @author helang
 * @since 2025-09-12
 */
@Service
@Slf4j
@AllArgsConstructor
public class NoAuthService {

    private JwtManager jwtManager;

    private AuthConfig authConfig;

    /**
     * 只要refreshToken有效就能刷新 不管token是否过期
     *
     * @param request httpRequest
     * @return 新的token和refreshToken 以及对应过期时间
     */
    public Result<RefreshTokenResult> refreshToken(HttpServletRequest request) {
        String token = this.parseToken(request.getHeader(authConfig.getTokenKey()));
        log.info("token是否有效:{}", jwtManager.validateToken(token));
        String refreshToken = this.parseToken(request.getHeader(authConfig.getRefreshTokenKey()));
        boolean flag = jwtManager.validateToken(refreshToken);
        log.info("refreshToken是否有效:{}", flag);
        if (flag) {
            //有效
            Claims claims = jwtManager.extractAllClaims(refreshToken);
            String username = jwtManager.extractUsername(refreshToken);
            HashMap<String, Object> extData = new HashMap<>(16);
            extData.put("phone", claims.get("phone"));
            extData.put("lastLoginDate", claims.get("lastLoginDate"));
            String newRefreshToken = jwtManager.createToken(username, extData, authConfig.getRefreshTime());
            String newToken = jwtManager.createToken(username, extData, authConfig.getExpireTime());

            RefreshTokenResult result = RefreshTokenResult.builder()
                    .token(newToken)
                    .refreshToken(newRefreshToken)
                    .expirationTime(authConfig.getExpireTime())
                    .refreshTime(authConfig.getRefreshTime()).build();
            return Result.success(result);
        }
        throw new RefreshTokenExpiredException();
    }

    private String parseToken(String token) {
        return (Objects.isNull(token) || token.isEmpty()) ? null : token.replace(authConfig.getTokenPrefix(), "").trim();
    }
}